<script setup>
import { ref, watch, reactive, nextTick, computed, watchEffect } from 'vue'
const question = ref('')//允许我们创建可以使用任何值类型的响应式 ref：ref() 将传入参数的值包装为一个带 .value 属性的 ref 对象：\
//ref 让我们能创造一种对任意值的 “引用”，并能够在不丢失响应性的前提下传递这些引用
const anser = ref('ccdd')
const refobj = {
  foo: ref(1),
  foo2: ref(2)
}
const { foo } = refobj//我们可以通过将 foo 改成顶层属性来解决 refobj.foo + 1生成object 的问题：
console.log('ref的组成', anser);

// 当 ref 作为响应式数组或像 Map 这种原生集合类型的元素被访问时，不会进行解包。
/**
 * reactive:
 * 1.仅对对象类型有效
 * 2.对string,number,boolean这样的原始类型无效
 * **/
const state = reactive({//reactive() 返回的是一个原始对象的 Proxy，它和原始对象是不相等的
  const: 1,
  arr: [2, 3, 4, 5,],
})

//监听函数
watch((question, (newv, oldv) => {
  //参数1：侦听数据源（可以是ref,计算属性，getter函数，响应式对象，以上类型的值组成的数组）:
  // 参数2回调函数，
  // 参数3配置选项
  // console.log(newv, oldv);
  anser.value = question.value
}))
watch((state, async (newv, oldv) => {
  console.log(state);
}))

const watchTarget = ref(0)

watchEffect(()=>{//进入页面就睡执行watchEffect中的函数，坚挺到依赖数据的变化回调函数就会被执行
  console.log(watchTarget.value)
})
// setInterval(()=>{
//   watchTarget.value++
// },500)



// 函数声明
const increment = () => {
  state.const++;
  console.log(document.getElementById('asa').textContent);//dom未更新时
  nextTick(() => {//当在 Vue 中更改响应式状态时，最终的 DOM 更新并不是同步生效的，而是由 Vue 将它们缓存在一个队列中，直到下一个“tick”才一起执行。这样是为了确保每个组件无论发生多少状态改变，都仅执行一次更新。
    console.log(document.getElementById('asa').textContent);//dom更新后
  })
}

//定义计算属性*
/**
 * 计算属性默认仅能通过计算函数得出庎，只在某些特殊场景中才需要用到可写属性
 * 计算属性没有副作用----不要在计算函数中做异步请求或者更改 DOM
 */
const firstName = ref('jjj')
const lastName = ref('lll')
const publicshedBooksMessage = computed(() => {//期望接受一个getter函数，返回值为一个计算属性ref，可以通过  publicshedBooksMessage.value访问结果
  return state.arr.length ? 'yes' : 'no'
})
//通过改变变量本身改变计算属性的值
const computedtwo = computed({
  get() {
    return firstName.value + '   ' + lastName.value;
  },
  set(newValue) {
    [firstName.value, lastName.value] = newValue.split(' ')
  }
})

const handleCompuend = () => {
  computedtwo.value = 'dadadadadadaad eee'
}
</script>

<template>
  <slot></slot>
  <input v-model="question" />
  <!-- 当 ref 在模板中作为顶层属性被访问时，它们会被自动“解包”，所以不需要使用 .value。 -->
  <!-- 注意：仅当 ref 是模板渲染上下文的顶层属性时才适用自动“解包” -->
  <p>{{  anser  }}</p>
  <p>{{  foo + 1  }}</p>
  <button @click="increment" id="asa">{{  state.const  }}</button>
  <br />
  <div>数组中有数据吗？{{  publicshedBooksMessage  }}</div>
  <br />
  <button @click="handleCompuend">点击改变计算属性的值</button>
  <p>{{ computedtwo }}</p>
</template>
